{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torchvision\n",
    "from torchvision.models.detection import FasterRCNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Users\\EDY\\anaconda3\\envs\\faceparsing\\lib\\site-packages\\torch\\functional.py:445: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at  ..\\aten\\src\\ATen\\native\\TensorShape.cpp:2157.)\n",
      "  return _VF.meshgrid(tensors, **kwargs)  # type: ignore[attr-defined]\n",
      "D:\\Users\\EDY\\anaconda3\\envs\\faceparsing\\lib\\site-packages\\torch\\nn\\functional.py:3702: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n",
      "  for i in range(dim)\n",
      "D:\\Users\\EDY\\anaconda3\\envs\\faceparsing\\lib\\site-packages\\torchvision\\models\\detection\\anchor_utils.py:123: UserWarning: __floordiv__ is deprecated, and its behavior will change in a future version of pytorch. It currently rounds toward 0 (like the 'trunc' function NOT 'floor'). This results in incorrect rounding for negative values. To keep the current behavior, use torch.div(a, b, rounding_mode='trunc'), or for actual floor division, use torch.div(a, b, rounding_mode='floor').\n",
      "  torch.tensor(image_size[1] // g[1], dtype=torch.int64, device=device)] for g in grid_sizes]\n",
      "D:\\Users\\EDY\\anaconda3\\envs\\faceparsing\\lib\\site-packages\\torchvision\\models\\detection\\anchor_utils.py:123: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n",
      "  torch.tensor(image_size[1] // g[1], dtype=torch.int64, device=device)] for g in grid_sizes]\n",
      "D:\\Users\\EDY\\anaconda3\\envs\\faceparsing\\lib\\site-packages\\torchvision\\models\\detection\\rpn.py:84: UserWarning: __floordiv__ is deprecated, and its behavior will change in a future version of pytorch. It currently rounds toward 0 (like the 'trunc' function NOT 'floor'). This results in incorrect rounding for negative values. To keep the current behavior, use torch.div(a, b, rounding_mode='trunc'), or for actual floor division, use torch.div(a, b, rounding_mode='floor').\n",
      "  A = Ax4 // 4\n",
      "D:\\Users\\EDY\\anaconda3\\envs\\faceparsing\\lib\\site-packages\\torchvision\\models\\detection\\rpn.py:85: UserWarning: __floordiv__ is deprecated, and its behavior will change in a future version of pytorch. It currently rounds toward 0 (like the 'trunc' function NOT 'floor'). This results in incorrect rounding for negative values. To keep the current behavior, use torch.div(a, b, rounding_mode='trunc'), or for actual floor division, use torch.div(a, b, rounding_mode='floor').\n",
      "  C = AxC // A\n",
      "D:\\Users\\EDY\\anaconda3\\envs\\faceparsing\\lib\\site-packages\\torchvision\\ops\\boxes.py:146: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n",
      "  boxes_x = torch.min(boxes_x, torch.tensor(width, dtype=boxes.dtype, device=boxes.device))\n",
      "D:\\Users\\EDY\\anaconda3\\envs\\faceparsing\\lib\\site-packages\\torchvision\\ops\\boxes.py:148: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n",
      "  boxes_y = torch.min(boxes_y, torch.tensor(height, dtype=boxes.dtype, device=boxes.device))\n",
      "D:\\Users\\EDY\\anaconda3\\envs\\faceparsing\\lib\\site-packages\\torchvision\\models\\detection\\transform.py:276: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n",
      "  for s, s_orig in zip(new_size, original_size)\n",
      "D:\\Users\\EDY\\anaconda3\\envs\\faceparsing\\lib\\site-packages\\torch\\onnx\\symbolic_opset9.py:2819: UserWarning: Exporting aten::index operator of advanced indexing in opset 11 is achieved by combination of multiple ONNX operators, including Reshape, Transpose, Concat, and Gather. If indices include negative values, the exported graph will produce incorrect results.\n",
      "  \"If indices include negative values, the exported graph will produce incorrect results.\")\n"
     ]
    }
   ],
   "source": [
    "model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)\n",
    "# For training\n",
    "images, boxes = torch.rand(4, 3, 600, 1200), torch.rand(4, 11, 4)\n",
    "boxes[:, :, 2:4] = boxes[:, :, 0:2] + boxes[:, :, 2:4]\n",
    "labels = torch.randint(1, 91, (4, 11))\n",
    "images = list(image for image in images)\n",
    "targets = []\n",
    "for i in range(len(images)):\n",
    "    d = {}\n",
    "    d['boxes'] = boxes[i]\n",
    "    d['labels'] = labels[i]\n",
    "    targets.append(d)\n",
    "output = model(images, targets)\n",
    "# For inference\n",
    "model.eval()\n",
    "x = [torch.rand(3, 300, 400), torch.rand(3, 500, 400)]\n",
    "predictions = model(x)\n",
    "# optionally, if you want to export the model to ONNX:\n",
    "torch.onnx.export(model, x, \"faster_rcnn.onnx\", opset_version = 11)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "torch.float32"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "images[0].dtype"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'loss_classifier': tensor(0.3693, grad_fn=<NllLossBackward0>),\n",
       " 'loss_box_reg': tensor(0.0317, grad_fn=<DivBackward0>),\n",
       " 'loss_objectness': tensor(2.0779, grad_fn=<BinaryCrossEntropyWithLogitsBackward0>),\n",
       " 'loss_rpn_box_reg': tensor(1.1996, grad_fn=<DivBackward0>)}"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "output"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([6, 5, 3, 3])\n"
     ]
    }
   ],
   "source": [
    "# roi pool\n",
    "from collections import OrderedDict\n",
    "m = torchvision.ops.MultiScaleRoIAlign(['feat1', 'feat3'], 3, 2)\n",
    "i = OrderedDict()\n",
    "i['feat1'] = torch.rand(1, 5, 64, 64)\n",
    "i['feat2'] = torch.rand(1, 5, 32, 32)  # this feature won't be used in the pooling\n",
    "i['feat3'] = torch.rand(1, 5, 16, 16)\n",
    "# create some random bounding boxes\n",
    "boxes = torch.rand(6, 4) * 256; boxes[:, 2:] += boxes[:, :2]\n",
    "# original image size, before computing the feature maps\n",
    "image_sizes = [(512, 512)]\n",
    "output = m(i, [boxes], image_sizes)\n",
    "print(output.shape)\n",
    "# torch.Size([6, 5, 3, 3])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "09f402a5df0ab33181308beb105cd67fedce8b63239961f335319bf6515a38ef"
  },
  "kernelspec": {
   "display_name": "Python 3.6.5 ('ps_torch')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
